package donot_to_bonc

import (
	"encoding/json"
	"errors"
	"fmt"
	"lifi"
	"lifi/internal"
	"lifi/plugins/transfers"
	"log"
	"os"
	"time"
)

const (
	layout       = "2006-01-02 15:04:05"
	goldenLayout = "2006/1/2 15:04:05.000"
)

var mapping map[string]MappingData = make(map[string]MappingData)

/*
	{
	    "CEMS.H400005": {
	        "bmp_number": "999001007",
	        "metrics": "current"
	    },
	    "CEMS.H400006": {
	        "bmp_number": "999001007",
	        "metrics": "voltage"
	    }
	}
*/
type Item struct {
	BmpNumber string `json:"bmp_number" yaml:"bmp_number"`
	Metrics   string `json:"metrics" yaml:"metrics"`
	Value     string `json:"value" yaml:"value"`
	Time      string `json:"time" yaml:"time"`
}
type MappingData struct {
	BmpNumber string `json:"bmp_number" yaml:"bmp_number"`
	Metrics   string `json:"metrics" yaml:"metrics"`
}

/*
	{
	         "CEMS.H400005": {
	           "Ms": 0,
	           "Value": "307",
	           "Time": "2022/3/27 11:26:24.000"
	         }
	       }
*/
type GoldenMetricValue struct {
	Ms    int    `json:"Ms" yaml:"Ms"`
	Value string `json:"Value" yaml:"Value"`
	Time  string `json:"Time" yaml:"Time"`
}

type GoldenMetricsTransfer struct {
	ConfigFile string `json:"configFile,omitempty" yaml:"configFile"`
}

func (d *GoldenMetricsTransfer) Init() error {

	mappingData, err := os.ReadFile(d.ConfigFile)
	if err != nil {
		log.Printf("Exit! Cause cannot open Config file : %v", err)
	}

	err = json.Unmarshal(mappingData, &mapping)
	if err != nil {
		log.Printf("Exit! Cause invalid config MappingFile :%s", d.ConfigFile)
	}
	return err
}

func (d *GoldenMetricsTransfer) Start(_ lifi.Collector) error {
	return nil
}

func (d *GoldenMetricsTransfer) Stop() {
}

func (d *GoldenMetricsTransfer) Process(data lifi.Data, acc lifi.Collector) error {
	var goldenMetrics map[string]GoldenMetricValue
	if bd, ok := data.(lifi.ByteData); ok {
		err := json.Unmarshal(bd.Data, &goldenMetrics)
		if err != nil {
			log.Printf("解析JSON时发生错误:%v", err)
			return err
		}
		var items []Item
		for k, v := range goldenMetrics {
			if mappingData, ok := mapping[k]; ok {
				bmp := mappingData.BmpNumber

				item := Item{
					BmpNumber: bmp,
					Metrics:   mappingData.Metrics,
					Value:     v.Value,
					Time:      v.Time,
				}
				items = append(items, item)

			} else {
				log.Printf("未找到对应的映射关系:%s", k)
			}
		}
		grouped := make(map[string][]Item)
		for _, i := range items {
			grouped[i.BmpNumber] = append(grouped[i.BmpNumber], i)
		}

		for bmp, items := range grouped {
			tname := fmt.Sprintf("d%s", bmp)

			tags := map[string]string{
				"bmp_number": bmp,
			}

			tm, err := internal.ParseTimestamp(goldenLayout, items[0].Time, time.Local)
			if err != nil {
				tm = time.Now()
			}
			sd := lifi.NewMetricData("device_metrics", tname, tags, nil, tm)

			for _, v := range items {
				vv, _ := internal.ToFloat64(v.Value)
				sd.AddField(v.Metrics, vv)
			}
			acc.Collect(sd)
		}
		return nil
	}

	return errors.New(string("unknow data:" + data.Group()))
}

var _ lifi.Transfer = &GoldenMetricsTransfer{}

func init() {
	transfers.Add("golden_device_metrics", func() lifi.Transfer {
		return &GoldenMetricsTransfer{}
	})
}
